socketio = require 'socket.io'
gusetNumber = 1
nickNames = {}
namesUsed = []
currentRoom = {}
io = null
###
  websocket location: D:\Documents\Programing\gruntstudy\Chapter1\node_modules\socket.io\node_modules\socket.io-client\node_modules\ws
  test
###
exports.listen = (server)->
  io = socketio.listen(server)
  io.set 'log level', 1

  io.sockets.on 'connection', (socket)->
    gusetNumber = assignGuestName socket

    joinRoom socket, 'Lobby'

    #handleMessageBroadcasting socket
    socket.on 'message',(message)->socket.broadcast.to(message.room).emit 'message', text: nickNames[socket.id] + ': '+ message.text

    handleNameChangeAttempts socket
    handleRoomJoining socket

    socket.on 'rooms', ()->socket.emit 'rooms', io.sockets.manager.rooms

    handleClientDisconnection socket


assignGuestName = (socket)->
  name = "Guest" + gusetNumber
  nickNames[socket.id] = name
  socket.emit 'nameResult', {success: true, name: name}
  namesUsed.push name
  return gusetNumber + 1

joinRoom = (socket, room)->
  socket.join room  # Make user join room
  currentRoom[socket.id] = room # Note that user is now in this room
  socket.emit 'joinResult', room: room # Let user know they're now in a new room

  socket.emit 'rooms', io.sockets.manager.rooms
  # Let other users in room know that a user has joined
  socket.broadcast.to(room).emit 'message', text: "#{nickNames[socket.id]} has joined #{room}."

  # Update other users room list

  usersInRoom = io.sockets.clients room # Determine what other users are in the same room as the user

  return unless usersInRoom.length > 1
  # if other user exist, summarize who they are
  usersInRoomSummary ="Users currently in #{room}: "
  otherusers = (nickNames[user.id] for user in usersInRoom when user.id != socket.id)
  usersInRoomSummary += otherusers.join ','

  socket.emit 'message', text: usersInRoomSummary # Send the summary of other users in the room to the user

handleNameChangeAttempts = (socket)->
  socket.on 'nameAttempt', (name)->
    if 0 == name.indexOf 'Guest'
      socket.emit 'nameResult', success: false, message: 'Names cannot begin with "Guest".'
      return
    if  -1 != namesUsed.indexOf name
      socket.emit 'nameResult', success: false, message: 'That name is already in use.'
      return

    previousName = nickNames[socket.id]
    previousNameIndex = namesUsed.indexOf(previousName)

    namesUsed.push name
    nickNames[socket.id] = name
    delete namesUsed[previousNameIndex]

    socket.emit 'nameResult', success: true, name: name

    socket.broadcast.to(currentRoom[socket.id]).emit 'message', text: "#{previousName} is now known as #{name}"

handleRoomJoining = (socket)->
  socket.on 'join', (room)->
    socket.leave currentRoom[socket.id]
    joinRoom(socket, room.newRoom)

handleClientDisconnection = (socket)->
  socket.on 'disconnect', ()->
    nameIndex = namesUsed.indexOf(nickNames[socket.id])
    delete namesUsed[nameIndex]
    delete nickNames[socket.id]
